package com.qwiki.text;

import java.util.ArrayList;
import java.util.Collections;
import java.util.List;

/**
 * Corresponds to an external link in wikipedia.
 * 
 * @author xgu
 * 
 * @since May 30, 2012
 */
public class ReferenceNode extends Node
{
  List<Node> children;

  @Override
  public String getText()
  {
    return "";
  }

  @Override
  public String getOriginalText()
  {
    return refname + " <> " + citation;
  }

  @Override
  public List<Node> getChildren()
  {
    return Collections.EMPTY_LIST;
  }

  // <ref name=> </ref>, <ref> </ref>, <ref name= />
  private static String prefix = "<ref";
  private static String closing = ">";
  private static String endclosing = "/>";
  private static String surfix2 = "</ref>"; // </ref>
  private static String surfix3 = "</ref"; // </ref>
  private static String surfix4 = ">"; // </ref>
  private static String name = "name";
  private static String group = "group";
  private static String assign = "=";
  private static String quote = "\"";
  private String citation;
  private String refname;

  @Override
  public boolean parse(char[] buffer, int start)
  {
    children = new ArrayList<Node>();
    this.start = start;
    this.buffer = buffer;
    int current = start;
    String suffix = null;
    if (!match(buffer, current, prefix))
      return false;
    current += prefix.length();
    int pos, grouppos=-1;
    int saveCurrent;
    if ((pos = match(buffer, current, closing, ' ')) >= 0)
    {
      // anonymous reference
      current = pos + closing.length();
      saveCurrent = current;
      while (current < buffer.length)
      {
        if (match(buffer, current, surfix2))
        {
          citation = new String(buffer, saveCurrent, current - saveCurrent);
          end = current + surfix2.length();
          parsed = true;
          return true;
        }
        current++;
      }
      return false;
    } else if ((pos = match(buffer, current, name, ' ')) >= 0 || (grouppos = match(buffer, current, group, ' '))>=0)
    {
      // named reference
      if (pos >0)
      {
        current = pos + name.length();
      } else if (grouppos>0)
      {
        current = grouppos + group.length();
      }
      pos = match(buffer, current, assign, ' ');
      if (pos < 0)
      {
        return false;
      }
      current = pos + assign.length();
      if ((pos = match(buffer, current, quote, ' ')) >= 0)
      {
        // name with quote
        current = pos + quote.length();
        // look for next quote
        if ((pos = find(buffer, quote, current)) >= 0)
        {
          // match end quote
          refname = new String(buffer, current, pos - current);
          current = pos + quote.length();
          // match tag closing
          while (current < buffer.length)
          {
            if (match(buffer, current, closing)) // "&gt;"
            {
              current += closing.length();
              // still need the content and end tag and the citation content
              break;
            }
            if ((pos = match(buffer, current, endclosing, ' ')) > 0) // "/&gt;"
            {
              parsed = true;
              end = pos + endclosing.length();
              // we are done, it is only a reference only.
              return true;
            }
            current++;
          }
        } else
        {
          return false;
        }
        // still need the content and end tag

      } else
      {
        // name without quote
        saveCurrent = current;
        while (current < buffer.length)
        {
          if (match(buffer, current, closing)) // "&gt;"
          {
            refname = new String(buffer, saveCurrent, current - saveCurrent);
            current += closing.length();
            // still need the content and end tag and the citation content
            break;
          }
          if ((pos = match(buffer, current, endclosing, ' ')) > 0) // "/&gt;"
          {
            refname = new String(buffer, saveCurrent, pos - saveCurrent);
            parsed = true;
            end = pos + endclosing.length();
            // we are done, it is only a reference only.
            return true;
          }
          current++;
        }
      }
      // still need the content and end tag and the citation content
      saveCurrent = current;
      while (current < buffer.length)
      {
        pos = match(buffer, current, surfix3, ' '); // "&lt;/ref"
        if (pos < 0)
        {
          current++;
          continue;
        }
        citation = new String(buffer, saveCurrent, pos - saveCurrent);
        current = pos + surfix3.length();
        pos = match(buffer, current, surfix4, ' '); // "&gt;"
        if (pos < 0)
        {
          current++;
          continue;
        }
        end = pos + surfix4.length();
        parsed = true;
        return true;
      }
      return false;
    } else
    {
      return false;
    }
  }

}
